package async.callback;

import org.apache.commons.lang3.StringUtils;
import reactor.core.publisher.Mono;
import reactor.core.scheduler.Schedulers;

/**
 * @auther zhouliangliang
 * @date 2022/9/29 16:10
 * @description
 */
public class AsyncWithReactor {
    private interface Callback{
       void doOnError(Exception e);
       void doOnSuccess(String value);
    }

    private static class A{
        public Mono invokeB(String value) {
            System.out.println("invoke B " + Thread.currentThread().getName());
            B b = new B();
            Mono mono = Mono.create(sink -> {
                b.doSomething(value, new Callback() {
                    @Override
                    public void doOnError(Exception e) {
                        System.out.println("in class A method doOnError!");
                        sink.error(new Exception("doOnError"));
                    }

                    @Override
                    public void doOnSuccess(String value) {
                        System.out.println("doOnSuccess " + Thread.currentThread().getName());
                        System.out.println("in class A method doOnSuccess!");
                        sink.success(value);
                    }
                });
            });
            System.out.println("exit invokeB");
            return mono;
        }
    }

    private static class B{
        public void doSomething(String value, Callback callback) {
            //sleep 2000ms
            try {
                Thread.sleep(2000);
            } catch (Exception e) {
                e.printStackTrace();
            }

            if(StringUtils.isEmpty(value)) {
                callback.doOnError(new Exception("value is empty"));
            } else {
                callback.doOnSuccess(new StringBuilder(value).reverse().toString());
            }
        }
    }

    public static void main(String[] args) throws Exception{
        A a = new A();
        a.invokeB("123456").subscribeOn(Schedulers.single()).subscribe(result->{
            System.out.println(result);
        }, e->{
            System.out.println(e);
        });
        Thread.sleep(3000);
    }
}